package ai

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io"
	"sync"
	"time"

	"workflow-gui/internal/protocol"
)

// AIClient 封装与 Claude Desktop 的通信
// 注意：MCP Server 已由 Claude Desktop 启动，无需再启动进程
type AIClient struct {
	stdin  io.Writer  // 向 Claude Desktop 发送请求
	stdout io.Reader  // 接收 Claude Desktop 的响应
	msgID  int        // JSON-RPC 消息 ID
	mu     sync.Mutex // 保护 msgID
}

// NewAIClient 创建 AI 客户端（使用现有 stdio）
// stdin: 用于向 Claude Desktop 发送请求
// stdout: 用于接收 Claude Desktop 的响应
func NewAIClient(stdin io.Writer, stdout io.Reader) *AIClient {
	return &AIClient{
		stdin:  stdin,
		stdout: stdout,
		msgID:  0,
	}
}

// CallClaude 发送提示词并等待响应
// prompt: 要发送给 Claude 的提示词
// 返回: AI 的响应内容
func (c *AIClient) CallClaude(prompt string) (string, error) {
	// 获取下一个消息 ID
	c.mu.Lock()
	c.msgID++
	msgID := c.msgID
	c.mu.Unlock()

	// 构造请求参数
	params := map[string]interface{}{
		"messages": []map[string]string{
			{
				"role":    "user",
				"content": prompt,
			},
		},
		"maxTokens": 4096,
	}

	paramsJSON, err := json.Marshal(params)
	if err != nil {
		return "", fmt.Errorf("failed to marshal params: %w", err)
	}

	// 构造 JSON-RPC 请求
	request := protocol.JSONRPCMessage{
		JSONRPC: "2.0",
		ID:      msgID,
		Method:  "sampling/createMessage",
		Params:  paramsJSON,
	}

	// 发送请求
	if err := c.sendRequest(request); err != nil {
		return "", fmt.Errorf("failed to send request: %w", err)
	}

	// 读取响应
	response, err := c.readResponse()
	if err != nil {
		return "", fmt.Errorf("failed to read response: %w", err)
	}

	// 检查错误
	if response.Error != nil {
		return "", fmt.Errorf("AI error: %s", response.Error.Message)
	}

	// 解析响应内容
	var result struct {
		Content []struct {
			Type string `json:"type"`
			Text string `json:"text"`
		} `json:"content"`
	}

	if err := json.Unmarshal(response.Result, &result); err != nil {
		return "", fmt.Errorf("failed to parse response: %w", err)
	}

	// 提取文本内容
	if len(result.Content) == 0 {
		return "", fmt.Errorf("empty response from AI")
	}

	return result.Content[0].Text, nil
}

// sendRequest 发送 JSON-RPC 请求
func (c *AIClient) sendRequest(request protocol.JSONRPCMessage) error {
	// 序列化请求
	data, err := json.Marshal(request)
	if err != nil {
		return fmt.Errorf("failed to marshal request: %w", err)
	}

	// 写入 stdin（添加换行符）
	if _, err := c.stdin.Write(append(data, '\n')); err != nil {
		return fmt.Errorf("failed to write to stdin: %w", err)
	}

	return nil
}

// readResponse 读取 JSON-RPC 响应
func (c *AIClient) readResponse() (*protocol.JSONRPCMessage, error) {
	// 使用 bufio.Scanner 读取一行
	scanner := bufio.NewScanner(c.stdout)

	// 设置超时（30 秒）
	done := make(chan bool)
	var response protocol.JSONRPCMessage
	var scanErr error

	go func() {
		if scanner.Scan() {
			scanErr = json.Unmarshal(scanner.Bytes(), &response)
		} else {
			scanErr = scanner.Err()
			if scanErr == nil {
				scanErr = fmt.Errorf("EOF")
			}
		}
		done <- true
	}()

	select {
	case <-done:
		if scanErr != nil {
			return nil, fmt.Errorf("failed to read response: %w", scanErr)
		}
		return &response, nil
	case <-time.After(30 * time.Second):
		return nil, fmt.Errorf("timeout waiting for response")
	}
}
